package com.example.guavaSrudy.basicFunction;

import com.google.common.base.*;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.text.SimpleDateFormat;
import java.util.*;

public class GuavaBasicUse{

    public static void main(String[] args) {
       Set<City> citys = Sets.newHashSet();
        for (int i = 0; i < 10; i++) {
            City city = new City();
            city.setName("changsha"+i);
            city.setPopulation(i);
            city.setZipCode("110"+i);
            citys.add(city);
        }
        HashMap<String, State> stateMap = Maps.newHashMap();
        State state = new State();
        state.setName("纽约州");
        state.setCode("456");
        state.setMainCities(citys);

        stateMap.put("NY",state);
        Function<String,State> lookup = Functions.forMap(stateMap,new State());
//        使用Functions.compose 聚合statefunction和lookup两个函数对象
        StateToCityString statefunction = new StateToCityString();

        Function<String, String> compose = Functions.compose(statefunction, lookup);
        /**
         * compose接收"NY"参数并调用lookup.apply()方法,这方法的返回值(state)被当作statefunction函数的apply()方法参数,
         * 最后statefunction函数的apply()方法的返回值返回给调用者.
         */
        System.out.println(compose.apply("NY"));
//        单独使用Functions.forMap
//        //Would return State object for NewYork
//        State ny = lookup.apply("NY1");
//        System.out.println(ny);
    }

    public static class DateFormatFunction implements Function<Date,String>{
        @Nullable
        @Override
        public String apply(@Nullable Date date) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");
            return simpleDateFormat.format(date);
        }
    }

    /**
     * 州
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class State {

        private String name;
        private String code;
        private Set<City> mainCities = new HashSet<City>();
        private String region;
    }

    /**
     * 城市
     */
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class City {

        private String name;
        private String zipCode;
        private int population;
        private String climate;
        private double region;

        @Override
        public String toString() {
            return name;
        }
    }

    /**
     * function
     */
    public static class StateToCityString implements Function<State,String> {

        @Override
        public String apply(State input) {
            return Joiner.on(",").join(input.getMainCities());
        }
    }
    /**
     * predicate
     */
    public class PopulationPredicate implements Predicate<City> {
        @Override
        public boolean apply(City input) {
            return input.getPopulation() <= 500000;
        }
    }
    public class RegionPredicate implements Predicate<State> {
        @Override
        public boolean apply(State input) {
            return input.getRegion().equalsIgnoreCase(Region.NORTHEAST);
        }
    }

    /**
     * Supplier
     */
    public class ComposedPredicateSupplier implements Supplier<Predicate<String>> {

        @Override
        public Predicate<String> get() {
            City city = new City("Austin,TX","12345",250000, Climate.SUB_TROPICAL,45.3);
            State state = new State("Texas","TX", Sets.newHashSet(city), Region.SOUTHWEST);
            City city1 = new City("New York,NY","12345",2000000,Climate.TEMPERATE,48.7);
            State state1 = new State("New York","NY",Sets.newHashSet(city1),Region.NORTHEAST);
            Map<String,State> stateMap = Maps.newHashMap();
            stateMap.put(state.getCode(),state);
            stateMap.put(state1.getCode(),state1);
            Function<String,State> mf = Functions.forMap(stateMap);
            return Predicates.compose(new RegionPredicate(), mf);
        }
    }
}